#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <string>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cerrno>
#include <stdio.h>
#include <unistd.h>

void Usage(const std::string& proc)
{
    std::cout << "you can use " << proc << " port" << std::endl;
}
int main(int argc, char* argv[])
{
    if(argc != 2)
    {
        Usage(argv[0]);
        return 0;
    }
    //1.创建套接字
    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    if(sock < 0)
    {
        std::cerr << "sock error" << std::endl;
        return 1;
    }
    const uint16_t port = (uint16_t)atoi(argv[1]);
    //2.绑定套接字
    struct sockaddr_in myaddr;
    myaddr.sin_family = AF_INET;
    myaddr.sin_port = htons(port);
    myaddr.sin_addr.s_addr = INADDR_ANY;
    if(bind(sock, (struct sockaddr*)&myaddr, sizeof(myaddr)) < 0)
    {
        std::cerr << "bind error" << std::endl;
        return 2;
    }
    //3.提供服务
    bool quit = false;
#define NUM 1024
    char buffer[NUM];
    while(!quit)
    {
        struct sockaddr_in peer;
        socklen_t len = sizeof(peer);
        
        ssize_t ret = recvfrom(sock, buffer, sizeof(buffer)-1, 0, (struct sockaddr*)&peer, &len);
        if(ret > 0)
        {
            std::cout << "client# " << buffer << std::endl;
            FILE* fp = popen(buffer, "r");
            std::string s;
            char line[NUM] = {0};
            while(fgets(line, sizeof(line), fp) != NULL)
            {
                s += line;
            }
            pclose(fp);
            sendto(sock, s.c_str(), s.size(), 0, (struct sockaddr*)&peer, len); 
        }
    }

    return 0;
}
